package Models;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import Export.CodeStorageContext;
import Interfaces.*;

public class Aplikace implements IDBItem{

	static String deleteString = "DELETE FROM" + CodeStorageContext.AplikaceTable + " OUTPUT DELETED.IDAplikace WHERE IDAplikace=";
	public static final String selectAplikace = "SELECT [IDAplikace], [IDUser], [Nazev], [Obsah], [FileName], [Popis], [DatumVytvoreni], [Ikona], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable +" app WHERE ";
	public static final String selectAplikaceLight = "SELECT [IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable +" app WHERE ";
	public static final String selectAplikaceList = "SELECT [IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable + " app";
	
	// TODO hodnota TOP je napevno - prototypovani
	public static final String selectNewList = "SELECT DISTINCT TOP 3 [IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable + " app ORDER BY [DatumVytvoreni] DESC";
	public static final String selectAplikaceTopHodList = "SELECT DISTINCT TOP 5 [IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable + " app ORDER BY AvgHodnota DESC";
	public static final String selectAplikaceTopStazList = "SELECT DISTINCT TOP 5 [IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable + " app ORDER BY [PocetStazeni] DESC";
	public static final String selectAplikaceWhereList = "SELECT app.[IDAplikace], [IDUser], [Nazev], [FileName], [Popis], [DatumVytvoreni], [DatumZmena], [PocetStazeni],(SELECT AVG(Hod.Hodnota) FROM Hodnoceni Hod Where Hod.IDAplikace = app.IDAplikace) as AvgHodnota FROM "+ CodeStorageContext.AplikaceTable + " app INNER JOIN [Tag] tag ON app.IDAplikace = tag.IDAplikace";
	
	public static final String selectAplikaceObsah = "SELECT [Obsah] FROM "+ CodeStorageContext.AplikaceTable +" WHERE ";
	public static final String selectAplikaceIkona = "SELECT [Ikona] FROM "+ CodeStorageContext.AplikaceTable +" WHERE ";
	
	public static String GetHodnoceniSaveParams(int idAplikace, String IP, float hodnota){
		StringBuilder sb = new StringBuilder();
		sb.append("INSERT INTO ");
		sb.append(CodeStorageContext.HodnoceniTable);
		sb.append(" ([IDAplikace],[IPAdresa],[Hodnota])");
		sb.append(" OUTPUT INSERTED.IDHodnoceni");
		sb.append(" VALUES (");
		sb.append(idAplikace + ", ");
		sb.append("'" + IP +"', ");
		sb.append(hodnota + ")");
		return sb.toString();
	}
	
	public static String getStazenoIncrement(int idAplikace){
		StringBuilder sb = new StringBuilder();
		sb.append("UPDATE ");
		sb.append(CodeStorageContext.AplikaceTable);
		sb.append(" SET PocetStazeni = PocetStazeni + 1 OUTPUT inserted.IDAplikace WHERE [IDAplikace] = ");
		sb.append(idAplikace);
		return sb.toString();
	}
	
	
	boolean isNew, isModified, isLocked, isAdmin;
	
	int idUser, idAplikace, pocetStazeni;
	byte[] content, ikona;
	Date datumVytvoreni, datumZmeny;
	String fileName, popis, nazev; 
	float prumerneHodnoceni;
	
	User masterObject;
	List<Tag> childs;
	
	
	public Aplikace(int idUser, String nazev, String popis, String fileName, byte[] content, byte[] ikona){
		// Datum vytvoreni
		datumVytvoreni = new Date();
		datumZmeny = datumVytvoreni;
		
		this.idUser = idUser;  
		this.nazev = nazev;
		this.popis = popis;
		this.fileName = fileName;
		this.content = content;
		this.ikona = ikona;
		
		isNew = true;
		isModified = false;
	}
	
	public Aplikace(User user, String nazev, String popis, String fileName, byte[] content, byte[] ikona){
		datumVytvoreni = new Date();
		datumZmeny = datumVytvoreni;
		
		this.masterObject = user;
		this.idUser = user.idUser;
		this.nazev = nazev;
		this.popis = popis;
		this.fileName = fileName;
		this.content = content;
		this.ikona = ikona;
		
		isNew = true;
		isModified = false;		
	}

	public Aplikace(int idAplikace, User user, String nazev, String popis, String fileName, Date datumVytvoreni, Date datumZmeny, byte[] content, byte[] ikona, float prumerneHodnoceni, int pocetStazeni, List<Tag> childs){
		this.datumVytvoreni = datumVytvoreni;
		this.datumZmeny = datumZmeny;
		
		this.masterObject = user;
		this.idUser = user.idUser;
		this.nazev = nazev;
		this.popis = popis;
		this.fileName = fileName;
		this.content = content;
		this.ikona = ikona;
		
		this.idAplikace = idAplikace;
		this.prumerneHodnoceni = prumerneHodnoceni;
		this.pocetStazeni = pocetStazeni;
		this.childs = childs;
		
		isNew = false;
		isModified = false;		
	}
	
	public Aplikace(int idAplikace, int idUser, String nazev, String popis, String fileName, Date datumVytvoreni, Date datumZmeny, byte[] content, byte[] ikona, float prumerneHodnoceni, int pocetStazeni, List<Tag> childs){
		this.datumVytvoreni = datumVytvoreni;
		this.datumZmeny = datumZmeny;
		
		this.idUser = idUser;
		this.nazev = nazev;
		this.popis = popis;
		this.fileName = fileName;
		this.content = content;
		this.ikona = ikona;
		
		this.idAplikace = idAplikace;
		this.prumerneHodnoceni= prumerneHodnoceni;
		this.pocetStazeni = pocetStazeni;
		this.childs = childs;
		
		isNew = false;
		isModified = false;
	}

	public Aplikace(int idAplikace, int idUser, String nazev, String popis, String fileName, Date datumVytvoreni, Date datumZmeny, float prumerneHodnoceni, int pocetStazeni, List<Tag> childs){
		this.datumVytvoreni = datumVytvoreni;
		this.datumZmeny = datumZmeny;
		
		this.idUser = idUser;
		this.nazev = nazev;
		this.popis = popis;
		this.fileName = fileName;
		this.content = null;
		this.ikona = null;
		
		this.idAplikace = idAplikace;
		this.prumerneHodnoceni= prumerneHodnoceni;
		this.pocetStazeni = pocetStazeni;
		this.childs = childs;
		
		isLocked = true;
	}	
	
	public int getPocetStazeni(){
		return pocetStazeni;
	}
	
	public String GetFileName(){
		return fileName;
	}
	
	public void SetFileName(String fileName){
		if(this.fileName.compareTo(fileName) != 0){
			this.fileName = fileName;
			isModified = true;
		}
	}
	
	public String getNazev(){
		return nazev;
	}
	
	public void setNazev(String nazev){
		if(this.nazev.compareTo(nazev) != 0){
			this.nazev = nazev;
			isModified = true;
		}
	}

	public String getPopis(){
		return popis;
	}
	
	public void setPopis(String popis){
		if(this.popis.compareTo(popis) != 0){
			this.popis = popis;
			isModified = true;
		}
	}
	
	public Float getPrumerHodnoceni(){
		return prumerneHodnoceni;
	}
	
	public void setPocetStazeni(int pocet){
			pocetStazeni = pocet;
	}
	
	public Date getDatumVytvoreni(){
		return datumVytvoreni;
		
	}
	
	public Date getDatumZmeny(){
		return datumZmeny;
	}
	
	public byte[] getObsah(){
		return content;
	}

	public void setObsah(byte[] obsah){
		this.content = obsah;
		isModified = true;
	}
	
	public byte[] getIkona(){
		return ikona;
	}
	
	public void setIkona(byte[] ikona){
		this.ikona = ikona;
		isModified = true;
	}
	
	
	public boolean isModified() {
		return isModified;
	}

	public boolean isNew() {
		return isNew;
	}

	public int getID() {
		return idAplikace;
	}

	public void setID(int id) {
		idAplikace = id;
		isNew = false;
		isModified = false;
	}

	public int  getMasterObjectID(){
		return idUser;
	}
	
	public IDBItem getMasterObject() {
		return masterObject;
	}

	public void setMasterObject(IDBItem masterObject)
	{
		this.masterObject = (User) masterObject;
		idUser = this.masterObject.idUser;
	}
	
	public List<IDBItem> getChilds() {
		if(childs != null)
		{
			List<IDBItem> output = new LinkedList<IDBItem>();
			for(Tag item : childs)
				output.add((IDBItem)item);
			return output;
		}
		return null;
	}
	
	public void setChilds(List<IDBItem> childs){
		if(childs != null){
			this.childs = new LinkedList<Tag>();
			for(IDBItem app : childs)
				this.childs.add((Tag) app);
		}
	}

	
	public List<Tag> getTags() {
		if(childs != null)
		{
			List<Tag> output = new LinkedList<Tag>();
			for(Tag item : childs)
				output.add(item);
			return output;
		}
		return null;
	}
	
	
	public String saveParams() {
		if(isLocked)
			return null;
		
		StringBuilder sb = new StringBuilder();
		if(isNew){			
			sb.append("INSERT INTO ");
			sb.append(CodeStorageContext.AplikaceTable);
			sb.append(" ([IDUser],[Nazev],[Obsah],[FileName],[Popis],[DatumVytvoreni],[Ikona],[DatumZmena])");
			sb.append(" OUTPUT INSERTED.IDAplikace");
			sb.append(" VALUES (");
			sb.append(idUser + ", ");
			sb.append("'" + nazev +"', ");
			sb.append("?, ");
			sb.append("'" + fileName +"', ");
			sb.append("'" + popis +"', ");
			sb.append("convert(datetime, '" + CodeStorageContext.GetSQLDateString(datumVytvoreni)  + "'), ");
			if(ikona != null)
				sb.append("?, ");	
			else
				sb.append("NULL, ");
			sb.append("convert(datetime, '" + CodeStorageContext.GetSQLDateString(datumZmeny)  + "')");
			sb.append(")");
			return sb.toString();
		}
		else{
			if(isModified){
				datumZmeny = new Date();
				sb.append("UPDATE ");
				sb.append(CodeStorageContext.AplikaceTable);
				sb.append(" SET");
				sb.append(" [Nazev]=");
				sb.append("'" + nazev + "', ");
				sb.append("[Popis]=");
				sb.append("'" + popis + "', ");
				sb.append("[FileName]=");
				sb.append("'" + fileName + "', ");
				sb.append("[DatumZmena]=");
				sb.append("convert(datetime, '" + CodeStorageContext.GetSQLDateString(datumZmeny)  + "'), ");
				sb.append("[PocetStazeni]=");
				sb.append("'" + pocetStazeni + "', ");
				sb.append("[Ikona]=");
				if(ikona != null)					
					sb.append("?, ");
				else
					sb.append("NULL, ");
				sb.append("[Obsah]=");
				sb.append("?");
				sb.append(" OUTPUT INSERTED.IDAplikace");
				sb.append(" WHERE [IDAplikace]=");
				sb.append(idAplikace);
				return sb.toString();
			}
		}
		return null;
	}

	public String deleteParams() {
		if(!isNew)
			return deleteString + idAplikace;
		return null;
	}

	public void setModified(boolean value) {
		isModified = true;
	}

}
